<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Equalizer design example</title>
<link rel="canonical" href="http://cvxr.com/cvx/examples/filter_design/html/equalizer_design.html">
<link rel="stylesheet" href="../../examples.css" type="text/css">
</head>
<body>
<div id="header">
<h1>Equalizer design example</h1>
Jump to:&nbsp;&nbsp;&nbsp;&nbsp;
<a href="#source">Source code</a>&nbsp;&nbsp;&nbsp;&nbsp;
<a href="#output">Text output</a>
&nbsp;&nbsp;&nbsp;&nbsp;
<a href="#plots">Plots</a>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="../../index.html">Library index</a>
</div>
<div id="content">
<a id="source"></a>
<pre class="codeinput">
<span class="comment">% "Filter design" lecture notes (EE364) by S. Boyd</span>
<span class="comment">% (figures are generated)</span>
<span class="comment">%</span>
<span class="comment">% Designs a frequency-domain and time-domain FIR equalizer for</span>
<span class="comment">% a single-input single-output (SISO) channel.</span>
<span class="comment">%</span>
<span class="comment">% Frequency-domain equalization uses a Chebychev criteria and</span>
<span class="comment">% is specified in terms of frequency response functions.</span>
<span class="comment">% It is a convex problem (which can be formulated as an SOCP):</span>
<span class="comment">%</span>
<span class="comment">%   minimize   max |G(w)H(w) - G_des(w)|     for w in [0,pi]</span>
<span class="comment">%</span>
<span class="comment">% where H is the frequency response function and our variable</span>
<span class="comment">% is the filter impulse response h. Function G is the unequalized</span>
<span class="comment">% frequency response and G_des is the desired freq response.</span>
<span class="comment">%</span>
<span class="comment">% Time-domain equalization immediately designs the impulse</span>
<span class="comment">% response function by specifying the problem in time (it's an LP):</span>
<span class="comment">%</span>
<span class="comment">%   minimize   max_{t neq D} |g_tilde(t)|</span>
<span class="comment">%       s.t.   g_tilde(D) = 1</span>
<span class="comment">%</span>
<span class="comment">% where g_tilde is the impulse response of equalized system,</span>
<span class="comment">% and D is the delay of the system.</span>
<span class="comment">%</span>
<span class="comment">% Written for CVX by Almir Mutapcic 02/02/06</span>

<span class="comment">%********************************************************************</span>
<span class="comment">% problem specs</span>
<span class="comment">%********************************************************************</span>
<span class="comment">% sample channel with impulse response g</span>
g =.5*[ 0.6526;  0.2157; -0.2639;  1.8024; -0.6430; <span class="keyword">...</span>
        0.1096; -0.7190;  0.4206; -0.0193;  0.6603;];

<span class="comment">% problem parameters</span>
n  = 30;              <span class="comment">% filter order</span>
D  = 10;              <span class="comment">% overall delay</span>

<span class="comment">%********************************************************************</span>
<span class="comment">% frequency domain equalization</span>
<span class="comment">%********************************************************************</span>
<span class="comment">% number of freq samples (rule-of-thumb)</span>
m  = 15*(length(g) + n);

w = linspace(0,pi,m)';
G = exp( -j*kron(w,[0:length(g)-1]) )*g;
A = exp( -j*kron(w,[0:n-1]) );

<span class="comment">% desired frequency response is a pure delay (equalized channel)</span>
Gdes = exp(-j*D*w);

<span class="comment">% formulate and solve the Chebyshev design problem</span>
cvx_begin
  variable <span class="string">hf(n,1)</span>
  minimize( max( abs( G.*(A*hf) - Gdes ) ) )
cvx_end

<span class="comment">% check if problem was successfully solved</span>
disp([<span class="string">'Frequency equalization problem is '</span> cvx_status])
<span class="keyword">if</span> ~strfind(cvx_status,<span class="string">'Solved'</span>)
  <span class="keyword">return</span>
<span class="keyword">end</span>

<span class="comment">%********************************************************************</span>
<span class="comment">% time-domain equalization</span>
<span class="comment">%********************************************************************</span>
<span class="comment">% define the convolution matrix</span>
Tconv = toeplitz([g; zeros(n-1,1)],[g(1) zeros(1,n-1)]);

<span class="comment">% create array of all times without t=D</span>
times_not_D = [1:D D+2:size(Tconv,1)];

<span class="comment">% formulate and solve the time equalization problem</span>
cvx_begin
  variable <span class="string">t</span>
  variable <span class="string">ht(n,1)</span>

  minimize( max( abs( Tconv(times_not_D,:)*ht ) ) )
  subject <span class="string">to</span>
    Tconv(D+1,:)*ht == 1;
cvx_end

<span class="comment">% check if problem was successfully solved</span>
<span class="keyword">if</span> ~strfind(cvx_status,<span class="string">'Solved'</span>)
  disp([<span class="string">'Frequency equalization problem is '</span> cvx_status])
  <span class="keyword">return</span>
<span class="keyword">end</span>

<span class="comment">%********************************************************************</span>
<span class="comment">% equalizer plots</span>
<span class="comment">%********************************************************************</span>
<span class="comment">% plot g</span>
figure(1)
plot([0:length(g)-1],g,<span class="string">'o'</span>,[0:length(g)-1],g,<span class="string">'b:'</span>)
xlabel(<span class="string">'t'</span>)
ylabel(<span class="string">'g(t)'</span>)

figure(2)
H = exp(-j*kron(w,[0:length(g)-1]))*g;
<span class="comment">% magnitude</span>
subplot(2,1,1);
plot(w,20*log10(abs(H)))
axis([0,pi,-20,20])
xlabel(<span class="string">'w'</span>)
ylabel(<span class="string">'mag G(w) in dB'</span>)
<span class="comment">% phase</span>
subplot(2,1,2)
plot(w,angle(H))
axis([0,pi,-pi,pi])
xlabel(<span class="string">'w'</span>)
ylabel(<span class="string">'phase G(w)'</span>)

<span class="comment">% freq equalizer</span>
figure(3)
plot([0:n-1],hf,<span class="string">'o'</span>,[0:n-1],hf,<span class="string">'b:'</span>)
xlabel(<span class="string">'t'</span>)
ylabel(<span class="string">'h(t)'</span>)

<span class="comment">% plot g_tilde</span>
figure(4)
gt=conv(g,hf);
plot([1:length(gt)]-1,gt,<span class="string">'o'</span>,[1:length(gt)]-1,gt,<span class="string">'b:'</span>)
xlabel(<span class="string">'t'</span>)
ylabel(<span class="string">'g tilde(t)'</span>)
axis([0,length(gt)-1,-.2 1.2])

figure(5)
H = exp(-j*kron(w,[0:length(gt)-1]))*gt;
<span class="comment">% amplitude</span>
subplot(2,1,1)
plot(w,20*log10(abs(H)))
axis([0,pi,-20,20])
xlabel(<span class="string">'w'</span>)
ylabel(<span class="string">'mag G tilde(w) in dB'</span>)
<span class="comment">% phase</span>
subplot(2,1,2)
plot(w,angle(H))
axis([0,pi,-pi,pi])
xlabel(<span class="string">'w'</span>)
ylabel(<span class="string">'phase G tilde(w)'</span>)

<span class="comment">% time equalizer</span>
figure(6)
plot([0:n-1],ht,<span class="string">'o'</span>,[0:n-1],ht,<span class="string">'b:'</span>)
xlabel(<span class="string">'t'</span>)
ylabel(<span class="string">'h(t)'</span>)

<span class="comment">% plot g_tilde</span>
figure(7)
gt=conv(g,ht);
plot([1:length(gt)]-1,gt,<span class="string">'o'</span>,[1:length(gt)]-1,gt,<span class="string">'b:'</span>)
xlabel(<span class="string">'t'</span>)
ylabel(<span class="string">'g tilde(t)'</span>)

figure(8)
H = exp(-j*kron(w,[0:length(gt)-1]))*gt;
<span class="comment">% magnitude</span>
subplot(2,1,1)
plot(w,20*log10(abs(H)))
axis([0,pi,-20,20])
xlabel(<span class="string">'w'</span>)
ylabel(<span class="string">'mag G tilde(w) in dB'</span>)
<span class="comment">% phase</span>
subplot(2,1,2)
plot(w,angle(H))
axis([0,pi,-pi,pi])
xlabel(<span class="string">'w'</span>)
ylabel(<span class="string">'phase G tilde(w)'</span>)
</pre>
<a id="output"></a>
<pre class="codeoutput">
 
Calling sedumi: 2399 variables, 631 equality constraints
   For improved efficiency, sedumi is solving the dual problem.
------------------------------------------------------------
SeDuMi 1.21 by AdvOL, 2005-2008 and Jos F. Sturm, 1998-2003.
Alg = 2: xz-corrector, Adaptive Step-Differentiation, theta = 0.250, beta = 0.500
eqs m = 631, order n = 1801, dim = 2400, blocks = 600
nnz(A) = 37787 + 0, nnz(ADA) = 38761, nnz(L) = 19696
 it :     b*y       gap    delta  rate   t/tP*  t/tD*   feas cg cg  prec
  0 :            4.03E+02 0.000
  1 :  -1.72E+00 1.84E+02 0.000 0.4558 0.9000 0.9000   1.49  1  1  5.1E+02
  2 :  -7.16E-01 4.18E+01 0.000 0.2273 0.9000 0.9000   4.27  1  1  2.9E+01
  3 :  -1.88E-01 1.45E+01 0.000 0.3481 0.9000 0.9000   5.14  1  1  2.6E+00
  4 :  -1.22E-01 6.11E+00 0.000 0.4202 0.9000 0.9000   2.31  1  1  7.4E-01
  5 :  -1.06E-01 2.57E+00 0.000 0.4201 0.9000 0.9000   1.40  1  1  2.7E-01
  6 :  -9.94E-02 1.03E+00 0.000 0.4017 0.9000 0.9000   1.16  1  1  1.0E-01
  7 :  -9.70E-02 3.90E-01 0.000 0.3781 0.9000 0.9000   1.06  1  1  3.9E-02
  8 :  -9.66E-02 1.54E-01 0.000 0.3955 0.9000 0.9000   1.02  1  1  1.5E-02
  9 :  -9.66E-02 4.74E-02 0.000 0.3073 0.9000 0.0000   1.00  1  1  5.9E-03
 10 :  -9.65E-02 1.72E-02 0.000 0.3620 0.9023 0.9000   1.00  1  1  2.1E-03
 11 :  -9.64E-02 5.47E-03 0.000 0.3191 0.9129 0.9000   1.00  1  1  7.3E-04
 12 :  -9.64E-02 1.63E-03 0.000 0.2985 0.9192 0.9000   1.00  1  1  2.3E-04
 13 :  -9.64E-02 6.75E-04 0.000 0.4133 0.9018 0.9000   1.00  1  1  9.6E-05
 14 :  -9.64E-02 2.84E-04 0.000 0.4206 0.9000 0.0000   1.00  1  1  4.5E-05
 15 :  -9.64E-02 5.38E-05 0.000 0.1894 0.9168 0.9000   1.00  1  1  9.6E-06
 16 :  -9.64E-02 1.51E-05 0.000 0.2799 0.9051 0.9000   1.00  1  1  2.8E-06
 17 :  -9.64E-02 5.01E-06 0.000 0.3331 0.9008 0.9000   1.00  1  1  9.3E-07
 18 :  -9.64E-02 1.46E-06 0.000 0.2920 0.9000 0.0000   1.00  1  1  3.6E-07
 19 :  -9.64E-02 2.07E-07 0.000 0.1411 0.9302 0.9000   1.00  1  1  7.2E-08
 20 :  -9.64E-02 3.98E-08 0.000 0.1928 0.9067 0.9000   1.00  1  3  1.4E-08

iter seconds digits       c*x               b*y
 20      0.2   Inf -9.6426279347e-02 -9.6426277108e-02
|Ax-b| =   1.1e-08, [Ay-c]_+ =   3.2E-09, |x|=  4.5e-01, |y|=  1.1e+00

Detailed timing (sec)
   Pre          IPM          Post
4.000E-02    2.500E-01    0.000E+00    
Max-norms: ||b||=1, ||c|| = 1,
Cholesky |add|=1, |skip| = 0, ||L.L|| = 103.515.
------------------------------------------------------------
Status: Solved
Optimal value (cvx_optval): +0.0964263
Frequency equalization problem is Solved
 
Calling sedumi: 115 variables, 69 equality constraints
   For improved efficiency, sedumi is solving the dual problem.
------------------------------------------------------------
SeDuMi 1.21 by AdvOL, 2005-2008 and Jos F. Sturm, 1998-2003.
Alg = 2: xz-corrector, Adaptive Step-Differentiation, theta = 0.250, beta = 0.500
Split 1 free variables
eqs m = 69, order n = 117, dim = 117, blocks = 1
nnz(A) = 790 + 0, nnz(ADA) = 1235, nnz(L) = 652
 it :     b*y       gap    delta  rate   t/tP*  t/tD*   feas cg cg  prec
  0 :            5.33E+01 0.000
  1 :  -7.57E-01 2.86E+01 0.000 0.5357 0.9000 0.9000   2.95  1  1  3.6E+01
  2 :  -3.77E-02 1.57E+01 0.000 0.5500 0.9000 0.9000  14.02  1  1  1.9E+00
  3 :  -2.50E-02 9.62E+00 0.000 0.6123 0.9000 0.9000   2.62  1  1  8.6E-01
  4 :  -3.15E-02 4.82E+00 0.000 0.5013 0.9000 0.9000   1.44  1  1  4.1E-01
  5 :  -3.19E-02 1.71E+00 0.000 0.3534 0.9000 0.9000   1.21  1  1  1.4E-01
  6 :  -3.19E-02 5.83E-01 0.000 0.3422 0.9000 0.9000   1.05  1  1  4.6E-02
  7 :  -3.17E-02 1.57E-01 0.000 0.2693 0.9000 0.9000   1.01  1  1  1.2E-02
  8 :  -3.17E-02 2.58E-02 0.000 0.1645 0.9000 0.0000   0.99  1  1  4.0E-03
  9 :  -3.17E-02 6.73E-04 0.000 0.0260 0.9442 0.9000   0.99  1  1  4.0E-04
 10 :  -3.16E-02 1.32E-04 0.000 0.1967 0.9000 0.8751   1.00  1  1  7.7E-05
 11 :  -3.16E-02 7.52E-06 0.000 0.0568 0.9904 0.9900   1.00  1  1  5.4E-06
 12 :  -3.16E-02 7.66E-07 0.000 0.1020 0.9138 0.9000   1.00  1  1  7.3E-07
 13 :  -3.16E-02 2.84E-08 0.000 0.0370 0.9900 0.9903   1.00  1  3  
iter seconds digits       c*x               b*y
 13      0.1   Inf -3.1625048704e-02 -3.1625048704e-02
|Ax-b| =   4.1e-16, [Ay-c]_+ =   3.0E-17, |x|=  7.7e-01, |y|=  1.1e+00

Detailed timing (sec)
   Pre          IPM          Post
2.000E-02    5.000E-02    0.000E+00    
Max-norms: ||b||=1, ||c|| = 1,
Cholesky |add|=1, |skip| = 0, ||L.L|| = 253.259.
------------------------------------------------------------
Status: Solved
Optimal value (cvx_optval): +0.031625
</pre>
<a id="plots"></a>
<div id="plotoutput">
<img src="equalizer_design__01.png" alt=""> <img src="equalizer_design__02.png" alt=""> <img src="equalizer_design__03.png" alt=""> <img src="equalizer_design__04.png" alt=""> <img src="equalizer_design__05.png" alt=""> <img src="equalizer_design__06.png" alt=""> <img src="equalizer_design__07.png" alt=""> <img src="equalizer_design__08.png" alt=""> 
</div>
</div>
</body>
</html>